<?php

declare(strict_types=1);

namespace App\Controller;

use Hyperf\Apidog\Annotation\DeleteApi;
use Hyperf\Apidog\Annotation\Path;
use Hyperf\Apidog\Annotation\PostApi;
use Hyperf\Apidog\Annotation\PutApi;
use Hyperf\DbConnection\Db;
use Hyperf\Apidog\Annotation\ApiController;
use Hyperf\Apidog\Annotation\FormData;
use Hyperf\Apidog\Annotation\GetApi;
use Hyperf\Apidog\Annotation\Query;
use Hyperf\Utils\Arr;
use Hyperf\Context\Context;
use App\Model\AdminMenu;
use App\Model\AdminRole;
use App\Model\AdminUser;

/**
 * @ApiController(prefix="roles", tag="角色管理", server="backend-api")
 */
class AdminRolesController extends AdminController
{
    /**
     * @GetApi(path="", description="角色列表")
     * @Query(key="page|页码", rule="integer|min:1")
     * @Query(key="per_page|x条/页", rule="integer|max:100")
     */
    public function index()
    {
        $data = AdminRole::with('operator:id,name')->paginate((int)$this->request->input('per_page', 10))->toArray();
        return $this->adminResponse(200, '请求成功', $data);
    }

    /**
     * @GetApi(path="options", description="选项")
     */
    public function options()
    {
        return $this->adminResponse(200, '请求成功', $this->buildOptions());
    }

    /**
     * 构建选项
     * @return array
     */
    protected function buildOptions()
    {
        return [
            'menu_tree' => AdminMenu::buildTree(),
        ];
    }

    /**
     * @PostApi(path="", description="添加角色")
     * @FormData(key="role_name|角色名称", rule="required")
     * @FormData(key="role_describe|角色描述", rule="")
     * @FormData(key="menu_permissions|权限菜单", rule="array|nullable")
     * @FormData(key="include_sites|所属站点", rule="")
     */
    public function store()
    {
        return $this->save();
    }

    /**
     * @GetApi(path="{id:\d+}", description="查看角色")
     * @Path(key="id|角色ID", rule="required|integer|exists:admin_roles")
     */
    public function show()
    {
        $data = [
            'admin_role' => AdminRole::find($this->request->route('id'))->toArray(),
        ];
        $data = Arr::merge($data, $this->buildOptions());
        return $this->adminResponse(200, '请求成功', $data);
    }

    /**
     * @PutApi(path="{id:\d+}", description="编辑角色")
     * @Path(key="id|角色ID", rule="required|integer|exists:admin_roles")
     * @FormData(key="role_name|角色名称", rule="required")
     * @FormData(key="role_describe|角色描述", rule="")
     * @FormData(key="menu_permissions|权限菜单", rule="array|nullable")
     * @FormData(key="include_sites|所属站点", rule="")
     */
    public function update()
    {
        return $this->save();
    }

    /**
     * 保存
     * @return mixed
     */
    protected function save()
    {
        $validator_data = Context::get('validator.data');
        isset($validator_data['include_sites']) && $validator_data['include_sites'] = explode(',', $validator_data['include_sites']);
        $AdminRole = Arr::has($validator_data, 'id') ? AdminRole::find(Arr::get($validator_data, 'id')) : new AdminRole();
        $validator_data['operator_id'] = $this->auth->id();
        $AdminRole->forceFill($validator_data)->save();
        return $this->adminResponse(200, '请求成功', $AdminRole->toArray());
    }

    /**
     * @DeleteApi(path="{id:\d+}", description="删除角色")
     * @Path(key="id|角色ID", rule="required|integer|exists:admin_roles")
     */
    public function destory()
    {
        Db::beginTransaction();
        try {
            $id = $this->request->route('id');
            AdminRole::where('id', $id)->delete();

            $user_count = AdminUser::where('role_id', $id)->count();
            if ($user_count)
                throw new \Exception('角色下有管理员，请先将管理员移除该角色再删除角色');

            Db::commit();
            return $this->adminResponse(200, '请求成功');
        } catch (\Throwable $ex) {
            Db::rollBack();
            return $this->adminResponse(400, $ex->getMessage());
        }
    }
}
